﻿/*********************************************************************************
**                                                                              **
**  Copyright (C) 2021-2025 LiLong                                              **
**  This file is part of CommonUnits.                                           **
**                                                                              **
**  CommonUnits is free software: you can redistribute it and/or modify         **
**  it under the terms of the GNU Lesser General Public License as published by **
**  the Free Software Foundation, either version 3 of the License, or           **
**  (at your option) any later version.                                         **
**                                                                              **
**  CommonUnits is distributed in the hope that it will be useful,              **
**  but WITHOUT ANY WARRANTY; without even the implied warranty of              **
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               **
**  GNU Lesser General Public License for more details.                         **
**                                                                              **
**  You should have received a copy of the GNU Lesser General Public License    **
**  along with CommonUnits.  If not, see <https://www.gnu.org/licenses/>.       **
**********************************************************************************/
#pragma once

#include "../CommonUnits.h"
#include "../UnitLists.h"

namespace CU
{
inline namespace Voltage
{
namespace Units
{
using V  = StandardUnit<"V">;
using mV = DeriveUnit<V, "mV", std::milli>;
using uV = DeriveUnit<V, "μV", std::micro>;
using nV = DeriveUnit<V, "nV", std::nano>;
using pV = DeriveUnit<V, "pV", std::pico>;
using fV = DeriveUnit<V, "fV", std::femto>;
using aV = DeriveUnit<V, "aV", std::atto>;
using kV = DeriveUnit<V, "kV", std::kilo>;
using MV = DeriveUnit<V, "MV", std::mega>;
using GV = DeriveUnit<V, "GV", std::giga>;
using TV = DeriveUnit<V, "TV", std::tera>;
using PV = DeriveUnit<V, "PV", std::peta>;
using EV = DeriveUnit<V, "EV", std::exa>;

using VoltageList = UnitLists<aV, fV, pV, nV, uV, mV, V, kV, MV, GV, TV, PV, EV>;
} // namespace Units
using Volt      = CommonUnits<double, Units::V>;
using Millivolt = CommonUnits<double, Units::mV>;
using Microvolt = CommonUnits<double, Units::uV>;
using Nanovolt  = CommonUnits<double, Units::nV>;
using Picovolt  = CommonUnits<double, Units::pV>;
using Femtovolt = CommonUnits<double, Units::fV>;
using Attovolt  = CommonUnits<double, Units::aV>;
using Kilovolt  = CommonUnits<double, Units::kV>;
using Megavolt  = CommonUnits<double, Units::MV>;
using Gigavolt  = CommonUnits<double, Units::GV>;
using Teravolt  = CommonUnits<double, Units::TV>;
using Petavolt  = CommonUnits<double, Units::PV>;
using Exavolt   = CommonUnits<double, Units::EV>;

namespace Literals
{
constexpr auto operator""_V(long double val) { return Volt(val); }
constexpr auto operator""_mV(long double val) { return Millivolt(val); }
constexpr auto operator""_uV(long double val) { return Microvolt(val); }
constexpr auto operator""_nV(long double val) { return Nanovolt(val); }
constexpr auto operator""_pV(long double val) { return Picovolt(val); }
constexpr auto operator""_fV(long double val) { return Femtovolt(val); }
constexpr auto operator""_aV(long double val) { return Attovolt(val); }
constexpr auto operator""_kV(long double val) { return Kilovolt(val); }
constexpr auto operator""_MV(long double val) { return Megavolt(val); }
constexpr auto operator""_GV(long double val) { return Gigavolt(val); }
constexpr auto operator""_TV(long double val) { return Teravolt(val); }
constexpr auto operator""_PV(long double val) { return Petavolt(val); }
constexpr auto operator""_EV(long double val) { return Exavolt(val); }
} // namespace Literals

template<typename Unit>
inline auto toUnit(double value, const std::string& dest) -> Unit
{
    return toUnitHelper<Unit, Units::VoltageList>(value, dest);
}
} // namespace Voltage
} // namespace CU
